Skip to main content

EMR Service Integration

The system is designed to dynamically support multiple EMR providers, including AthenaHealth and Tebra. The EMRService acts as a bridge between Bookadoc and the EMR providers, ensuring that the correct EMR system is loaded based on the provider’s business location.


EMRService: Managing Multiple EMR Integrations

Bookadoc’s EMRService dynamically selects and initializes the appropriate EMR integration based on the healthcare provider’s configuration.

How It Works

  1. When a request is made (e.g., book an appointment, fetch provider data), Bookadoc checks the business location’s EMR integration type.
  2. Based on the type, Bookadoc initializes the corresponding EMR class (AthenaEmr or TebraEmr).
  3. The selected EMR class handles the API requests and interactions with the respective EMR system.

Code Implementation

const { SUPPORTED_EMRS } = require('../interfaces/EmrInterface');
const { EmrIntegration } = require('../models/index');
const AthenaEmr = require('./Athena');
const TebraEmr = require('./Tebra');

class EMRService {
async getEMRService(businessLocationId, type = SUPPORTED_EMRS.TEBRA) {
const business_emr = await EmrIntegration.findOne({
where: { business_location_id: businessLocationId },
});

if (!business_emr) throw new Error(`No EMR Integration for this business location with ID ${businessLocationId}`);

const effectiveType = business_emr.type || type;

switch (effectiveType) {
case SUPPORTED_EMRS.TEBRA:
const tebra = new TebraEmr();
await tebra.init(business_emr);
return tebra;

case SUPPORTED_EMRS.ATHENA:
const athena = new AthenaEmr();
await athena.init(business_emr);
return athena;

default:
throw new Error('Unknown EMR Integration');
}
}
}

module.exports = new EMRService();

How It Works in Practice

  • When Bookadoc needs to book an appointment, it calls getEMRService(), passing the business location ID.
  • getEMRService() looks up the configured EMR for that location and loads either AthenaEmr or TebraEmr.
  • Once initialized, the selected EMR class handles the request (e.g., calling AthenaHealth’s API to create an appointment).

AthenaEmr: Bookadoc’s AthenaHealth Integration

The AthenaEmr class is responsible for interacting with AthenaHealth’s API.

Initialization

The init() function sets up the AthenaHealth API service with the required credentials.

async init(emrIntegration) {
const [credential] = emrIntegration?.credentials?.filter((cred) => cred?.type === AUTH_TYPE.USER);
if (!credential) throw Error('Athena user authentication credentials not found');

this.service = new AthenaApiService(credential, emrIntegration.practice_id);
this.location = emrIntegration.BusinessLocation;
this.practice_id = emrIntegration.practice_id;
this.practice_name = emrIntegration.practice_name;
this.emrIntegration = emrIntegration;
}

Handling Appointments

The AthenaEmr class includes functions for managing appointments:

FunctionDescription
getOpenAppointmentSlots()Fetches available appointment slots from AthenaHealth.
createAppointment()Creates a new appointment in AthenaHealth.
updateAppointment()Updates an existing appointment.
cancelAppointment()Cancels an appointment in AthenaHealth.
getTelehealthInviteUrl()Retrieves the Telehealth invite URL for virtual appointments.

Example of creating an appointment:

async createAppointment(payload = {}) {
const external_data = JSON.parse(payload?.ExternalData);
const transformPayload = {
appointmentId: external_data?.appointment_id,
appointmentData: {
patientid: payload?.PatientId,
departmentid: external_data?.department_id,
appointmenttypeid: external_data?.appointmenttypeid,
ignoreschedulablepermission: true,
},
};

return this.service.createAppointment(transformPayload);
}

Example of rescheduling an appointment:

async updateAppointment(payload = {}) {
if (payload?.OldAppointmentId) {
await this.cancelAppointment({
CancelReasonId: 83,
AppointmentId: payload?.OldAppointmentId,
PatientId: payload?.PatientId,
Notes: 'Rescheduling appointment',
});
}

return this.createAppointment(payload);
}

TebraEmr: Alternative EMR Integration

If a provider uses Tebra instead of AthenaHealth, Bookadoc loads TebraEmr, which follows a similar structure but communicates with Tebra’s API.

case SUPPORTED_EMRS.TEBRA:
const tebra = new TebraEmr();
await tebra.init(business_emr);
return tebra;

Benefits of Bookadoc’s EMR Integration

  1. Dynamic EMR Selection – Bookadoc automatically loads the correct EMR for each provider.
  2. Scalability – Additional EMR systems can be integrated in the future.
  3. Seamless API Handling – Bookadoc abstracts API complexities, allowing providers to focus on patient care.
  4. Real-Time Synchronization – Ensures appointments, patient data, and provider schedules are always up to date.

Conclusion

The EMR Service Integration in Bookadoc enables seamless communication with AthenaHealth and other EMRs like Tebra. By dynamically selecting the correct EMR based on the provider’s business location, Bookadoc ensures efficient appointment scheduling, patient data management, and system interoperability.